package com.guyu.plugin.satoken.exception;


import cn.dev33.satoken.exception.DisableServiceException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.exception.SaTokenException;
import com.guyu.common.core.entity.BizResult;
import com.guyu.common.web.util.GuyuServletUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * <p> Sa-Token异常捕捉 </p>
 */
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
public class SaTokenExceptionHandler {


    /**
     * Sa-Token认证异常
     */
    @ExceptionHandler(value = SaTokenException.class)
    public BizResult saTokenExceptionHandler(HttpServletRequest request, SaTokenException e) {
        log.error("[GUYU]Sa-Token认证异常, url:[ {} ], param:[ {} ], body:[ {} ]",
                request.getRequestURI(), GuyuServletUtils.getParams(request), GuyuServletUtils.getRequestBody(request), e);
        return BizResult.error(SaTokenErrorCodeEnum.UNAUTHORIZED, e.getMessage());
    }

    /**
     * 登录认证异常
     */
    @ExceptionHandler(value = NotLoginException.class)
    public BizResult notLoginExceptionHandler(HttpServletRequest request, NotLoginException e) {
        log.error("[GUYU]登录认证异常, url:[ {} ], param:[ {} ], body:[ {} ]",
                request.getRequestURI(), GuyuServletUtils.getParams(request), GuyuServletUtils.getRequestBody(request), e);
        String message = "";
        if (e.getType().equals(NotLoginException.NOT_TOKEN)) {
            message = "认证失败，无法访问系统资源";
        } else if (e.getType().equals(NotLoginException.INVALID_TOKEN)) {
            message = "无效的token";
        } else if (e.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
            message = "token 已过期";
        } else if (e.getType().equals(NotLoginException.BE_REPLACED)) {
            message = "token 已被顶下线";
        } else if (e.getType().equals(NotLoginException.KICK_OUT)) {
            message = "token 已被踢下线";
        } else if (e.getType().equals(NotLoginException.TOKEN_FREEZE)) {
            message = "token 已被冻结";
        } else if (e.getType().equals(NotLoginException.NO_PREFIX)) {
            message = "认证失败，无法访问系统资源";
        } else {
            message = "认证失败，无法访问系统资源";
        }
        return BizResult.error(SaTokenErrorCodeEnum.RELOGIN, message);
    }

    /**
     * 权限认证异常
     */
    @ExceptionHandler(value = NotPermissionException.class)
    public BizResult notPermissionExceptionHandler(HttpServletRequest request, NotPermissionException e) {
        log.error("[GUYU]权限认证异常, url:[ {} ], param:[ {} ], body:[ {} ]",
                request.getRequestURI(), GuyuServletUtils.getParams(request), GuyuServletUtils.getRequestBody(request), e);
        return BizResult.error(SaTokenErrorCodeEnum.NOT_PERMISSION, e.getMessage());
    }

    /**
     * 角色认证异常
     */
    @ExceptionHandler(value = NotRoleException.class)
    public BizResult notRoleExceptionHandler(HttpServletRequest request, NotRoleException e) {
        log.error("[GUYU]角色认证异常, url:[ {} ], param:[ {} ], body:[ {} ]",
                request.getRequestURI(), GuyuServletUtils.getParams(request), GuyuServletUtils.getRequestBody(request), e);
        return BizResult.error(SaTokenErrorCodeEnum.NOT_ROLE, e.getMessage());
    }

    /**
     * 账号的指定服务已被封禁
     */
    @ExceptionHandler(value = DisableServiceException.class)
    public BizResult disableServiceExceptionHandler(HttpServletRequest request, DisableServiceException e) {
        log.error("[GUYU]账号的指定服务已被封禁, url:[ {} ], param:[ {} ], body:[ {} ]",
                request.getRequestURI(), GuyuServletUtils.getParams(request), GuyuServletUtils.getRequestBody(request), e);
        return BizResult.error(SaTokenErrorCodeEnum.FORBIDDEN, e.getMessage());
    }
}
